home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / xinetd.2.0.6 / conf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  12.9 KB  |  569 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: conf.c,v 5.3 1993/01/14 01:57:56 panos Exp $" ;
  8.  
  9. #include <sys/types.h>
  10. #include <netinet/in.h>
  11. #include <syslog.h>
  12. #include <fcntl.h>
  13. #include <string.h>
  14. #include <netdb.h>
  15.  
  16. #include "pset.h"
  17. #include "misc.h"
  18. #include "xlog.h"
  19.  
  20. #include "attr.h"
  21. #include "defs.h"
  22. #include "service.h"
  23. #include "conf.h"
  24. #include "state.h"
  25. #include "config.h"
  26. #include "logoptions.h"
  27.  
  28. char *malloc() ;
  29. void endservent() ;
  30. void endprotoent() ;
  31. void endrpcent() ;
  32.  
  33. void msg() ;
  34. void out_of_memory() ;
  35.  
  36. PRIVATE status_e conf_setup() ;
  37. PRIVATE status_e fix_server_argv() ;
  38. PRIVATE status_e attr_fill() ;
  39. PRIVATE void remove_disabled_services() ;
  40. PRIVATE status_e attr_check() ;
  41. PRIVATE status_e check_entry() ;
  42. PRIVATE void dump_configuration() ;
  43.  
  44. /*
  45.  * Pset iterator used by functions in this file.
  46.  * It lives only when get_configuration is called (i.e. it is created and
  47.  * destroyed each time). This is because the pset it is iterating on
  48.  * changes.
  49.  */
  50. static psi_h iter ;
  51.  
  52.  
  53. #define CHECK_AND_CLEAR( scp, mask, mask_name )                                            \
  54.     if ( M_IS_SET( mask, LO_USERID ) )                                                        \
  55.     {                                                                                                    \
  56.         msg( LOG_WARNING, func,                                                                    \
  57.             "%s service: clearing USERID option from %s", scp->id, mask_name ) ;    \
  58.         M_CLEAR( mask, LO_USERID ) ;                                                            \
  59.     }
  60.  
  61.  
  62. status_e get_configuration( confp )
  63.     struct configuration *confp ;
  64. {
  65.     int config_fd ;
  66.     struct service *sp ;
  67.     void parse_conf_file() ;
  68.     char *func = "get_configuration" ;
  69.  
  70.     if ( conf_setup( &config_fd, confp, &iter ) == FAILED )
  71.         return( FAILED ) ;
  72.  
  73.     parse_conf_file( config_fd, confp ) ;
  74.     Sclose( config_fd ) ;
  75.  
  76.     remove_disabled_services( confp ) ;
  77.  
  78.     for ( sp = SP( psi_start( iter ) ) ; sp ; sp = SP( psi_next( iter ) ) )
  79.     {
  80.         struct service_config *scp = CONF( sp ) ;
  81.  
  82.         if ( check_entry( sp ) == FAILED )
  83.         {
  84.             svc_free( sp ) ;
  85.             psi_remove( iter ) ;
  86.             continue ;
  87.         }
  88.         if ( attr_fill( scp, CONF( confp->defaults ) ) == FAILED )
  89.         {
  90.             svc_free( sp ) ;
  91.             psi_remove( iter ) ;
  92.             continue ;
  93.         }
  94.  
  95.         /*
  96.          * If the INTERCEPT flag is set, change this service to an internal 
  97.          * service using the special INTERCEPT builtin.
  98.          */
  99.         if ( IS_INTERCEPTED( scp ) )
  100.         {
  101.             sp->builtin = find_special_builtin( INTERCEPT_SERVICE_NAME,
  102.                                                                         scp->socket_type ) ;
  103.             if ( sp->builtin == NULL )
  104.             {
  105.                 msg( LOG_ERR, func, "removing service %s", scp->id ) ;
  106.                 svc_free( sp ) ;
  107.                 psi_remove( iter ) ;
  108.                 continue ;
  109.             }
  110.             M_SET( scp->type, ST_INTERNAL ) ;
  111.         }
  112.  
  113.         /*
  114.          * Clear the USERID flag for the identity service because
  115.          * it may lead to loops (for example, remote xinetd issues request,
  116.          * local xinetd issues request to remote xinetd etc.)
  117.          * We identify the identity service by its (protocol,port) combination.
  118.          */
  119.         if ( scp->port == IDENTITY_SERVICE_PORT && 
  120.                                                     scp->protocol.value == IPPROTO_TCP )
  121.         {
  122.             CHECK_AND_CLEAR( scp, scp->log_on_success, "log_on_success" ) ;
  123.             CHECK_AND_CLEAR( scp, scp->log_on_failure, "log_on_failure" ) ;
  124.         }
  125.     }
  126.  
  127.     psi_destroy( iter ) ;
  128.  
  129.     if ( debug.on )
  130.     {
  131.         int fd = -1 ;
  132.  
  133.         xlog_control( ps.rws.program_log, XLOG_GETFD, &fd ) ;
  134.         if ( fd != -1 )
  135.             dump_configuration( confp, fd ) ;
  136.     }
  137.  
  138.     endservent() ;
  139.     endprotoent() ;
  140. #ifndef NO_RPC
  141.     endrpcent() ;
  142. #endif
  143.     return( OK ) ;
  144. }
  145.  
  146.  
  147. void free_configuration( confp )
  148.     struct configuration *confp ;
  149. {
  150.     register unsigned u ;
  151.  
  152.     for ( u = 0 ; u < pset_count( confp->services ) ; u++ )
  153.     {
  154.         struct service *sp = SP( pset_pointer( confp->services, u ) ) ;
  155.  
  156.         if ( sp->ref_count == 0 )
  157.             svc_free( sp ) ;
  158.     }
  159.     pset_destroy( confp->services ) ;
  160.     if ( confp->defaults->ref_count == 0 )
  161.         svc_free( confp->defaults ) ;
  162. }
  163.  
  164.  
  165. void dump_current_configuration( fd )
  166.     int fd ;
  167. {
  168.     struct configuration current ;
  169.     void dump_configuration() ;
  170.  
  171.     current.services = SERVICES( ps ) ;
  172.     current.defaults = ps.rws.cs.defaults ;
  173.     dump_configuration( ¤t, fd ) ;
  174. }
  175.  
  176.  
  177. PRIVATE void dump_configuration( confp, fd )
  178.     struct configuration *confp ;
  179.     int fd ;
  180. {
  181.     void list_services() ;
  182.     void tabprint() ;
  183.  
  184.     sconf_dump( CONF( confp->defaults ), fd, 0, TRUE ) ;
  185.     tabprint( fd, 0, "\n" ) ;
  186.     list_services( confp->services, fd ) ;
  187. }
  188.  
  189.  
  190.  
  191. PRIVATE status_e conf_setup( fdp, confp, iterp )
  192.     int *fdp ;
  193.     struct configuration *confp ;
  194.     psi_h *iterp ;
  195. {
  196.     int fd ;
  197.     pset_h pset ;
  198.     psi_h pset_iter ;
  199.     struct service *sp ;
  200.     char *func = "conf_setup" ;
  201.  
  202.     /*
  203.      * Open configuration file
  204.      */
  205.    fd = open( ps.ros.config_file, O_RDONLY ) ;
  206.  
  207.    if ( fd == -1 )
  208.    {
  209.       msg( LOG_CRIT, func, "open( %s ) failed: %m", ps.ros.config_file ) ;
  210.         return( FAILED ) ;
  211.    }
  212.  
  213.     if ( ( pset = pset_create( 0, 0 ) ) == NULL )
  214.     {
  215.         msg( LOG_CRIT, func, "can't create service table" ) ;
  216.         (void) close( fd ) ;
  217.         return( FAILED ) ;
  218.     }
  219.  
  220.     if ( ( sp = svc_new( (struct service_config *)NULL ) ) == NULL )
  221.     {
  222.         msg( LOG_CRIT, func, "can't allocate defaults service" ) ;
  223.         pset_destroy( pset ) ;
  224.         (void) close( fd ) ;
  225.         return( FAILED ) ;
  226.     }
  227.  
  228.     if ( ( pset_iter = psi_create( pset ) ) == NULL )
  229.     {
  230.         msg( LOG_CRIT, func, "can't create service table iterator" ) ;
  231.         svc_free( sp ) ;
  232.         pset_destroy( pset ) ;
  233.         (void) close( fd ) ;
  234.         return( FAILED ) ;
  235.     }
  236.  
  237.     *fdp = fd ;
  238.     confp->services = pset ;
  239.     confp->defaults = sp ;
  240.     *iterp = pset_iter ;
  241.     return( OK ) ;
  242. }
  243.  
  244.  
  245. PRIVATE status_e fix_server_argv( scp )
  246.     struct service_config *scp ;
  247. {
  248.     char *server_name ;
  249.     char *func = "fix_server_argv" ;
  250.  
  251.     /*
  252.      * Check if the user specified any server arguments.
  253.      * If not, then the server_argv has not been allocated yet,
  254.      * so malloc it (size 2)
  255.      * Put in argv[ 0 ] the last component of the server pathname
  256.      */
  257.     if ( ! SPECIFIED( scp, A_SERVER_ARGS ) )
  258.     {
  259.         scp->server_argv = (char **) malloc( 2 * sizeof( char * ) ) ;
  260.         if ( scp->server_argv == NULL )
  261.         {
  262.             out_of_memory( func ) ;
  263.             return( FAILED ) ;
  264.         }
  265.         scp->server_argv[ 1 ] = NULL ;
  266.         PRESENT( scp, A_SERVER_ARGS ) ;
  267.     }
  268.  
  269.     /*
  270.      * Determine server name
  271.      */
  272.     server_name = strrchr( scp->server, '/' ) ;
  273.     if ( server_name == NULL )
  274.         server_name = scp->server ;
  275.     else
  276.         server_name++ ;      /* skip the '/' */
  277.  
  278.     /*
  279.      * Place it in argv[ 0 ]
  280.      */
  281.     scp->server_argv[ 0 ] = make_string( 1, server_name ) ;
  282.     if ( scp->server_argv[ 0 ] == NULL )
  283.     {
  284.         out_of_memory( func ) ;
  285.         return( FAILED ) ;
  286.     }
  287.     return( OK ) ;
  288. }
  289.  
  290.  
  291.  
  292. #define USE_DEFAULT( scp, def, attr_id )    \
  293.             ( ! SPECIFIED( scp, attr_id ) && SPECIFIED( def, attr_id ) )
  294.  
  295. PRIVATE status_e attr_fill( scp, def )
  296.     struct service_config *scp ;
  297.     struct service_config *def ;
  298. {
  299.     char *func = "attr_fill" ;
  300.     status_e setup_environ() ;
  301.  
  302.     if ( ! IS_INTERNAL( scp ) && fix_server_argv( scp ) == FAILED )
  303.         return( FAILED ) ;
  304.  
  305.     if ( ! SPECIFIED( scp, A_INSTANCES ) )
  306.     {
  307.         scp->instances = SPECIFIED( def, A_INSTANCES ) ? def->instances
  308.                                                                       : DEFAULT_INSTANCE_LIMIT ;
  309.         PRESENT( scp, A_INSTANCES ) ;
  310.     }
  311.  
  312.     if ( USE_DEFAULT( scp, def, A_LOG_ON_SUCCESS ) )
  313.     {
  314.         scp->log_on_success = def->log_on_success ;
  315.         PRESENT( scp, A_LOG_ON_SUCCESS ) ;
  316.     }
  317.  
  318.     if ( USE_DEFAULT( scp, def, A_LOG_ON_FAILURE ) )
  319.     {
  320.         scp->log_on_failure = def->log_on_failure ;
  321.         PRESENT( scp, A_LOG_ON_FAILURE ) ;
  322.     }
  323.  
  324.     if ( USE_DEFAULT( scp, def, A_LOG_TYPE ) )
  325.     {
  326.         switch ( LOG( def )->log_type )
  327.         {
  328.             case L_NONE:
  329.                 LOG( scp )->log_type = L_NONE ;
  330.                 break ;
  331.             
  332.             case L_SYSLOG:
  333.                 LOG( scp )->log_type = L_SYSLOG ;
  334.                 SYSLOG( LOG( scp ) )->facility = SYSLOG( LOG( def ) )->facility ;
  335.                 SYSLOG( LOG( scp ) )->level = SYSLOG( LOG( def ) )->level ;
  336.                 break ;
  337.             
  338.             case L_FILE:
  339.                 LOG( scp )->log_type = L_COMMON_FILE ;
  340.                 break ;
  341.  
  342.             default:
  343.                 msg( LOG_ERR, func,
  344.                                 "bad log type: %d", (int) LOG( def )->log_type ) ;
  345.                 return( FAILED ) ;
  346.         }
  347.         PRESENT( scp, A_LOG_TYPE ) ;
  348.     }
  349.     if ( setup_environ( scp, def ) == FAILED )
  350.         return( FAILED ) ;
  351.     return( OK ) ;
  352. }
  353.  
  354.  
  355. PRIVATE void remove_disabled_services( confp )
  356.     struct configuration *confp ;
  357. {
  358.     pset_h disabled_services ;
  359.     register struct service *sp ;
  360.     struct service_config *defaults = CONF( confp->defaults ) ;
  361.  
  362.     if ( ! SPECIFIED( defaults, A_DISABLED ) )
  363.         return ;
  364.     
  365.     disabled_services = defaults->disabled ;
  366.  
  367.     for ( sp = SP( psi_start( iter ) ) ; sp ; sp = SP( psi_next( iter ) ) )
  368.     {
  369.         register char *sid = CONF( sp )->id ;
  370.         register unsigned u ;
  371.  
  372.         for ( u = 0 ; u < pset_count( disabled_services ) ; u++ )
  373.             if ( EQ( sid, (char *) pset_pointer( disabled_services, u ) ) )
  374.             {
  375.                 svc_free( sp ) ;
  376.                 psi_remove( iter ) ;
  377.                 break ;
  378.             }
  379.     }
  380. }
  381.  
  382.  
  383. /*
  384.  * Check if all required attributes have been specified
  385.  */
  386. PRIVATE status_e attr_check( scp )
  387.     register struct service_config *scp ;
  388. {
  389.     mask_t necessary_and_specified ;
  390.     mask_t necessary_and_missing ;
  391.     mask_t must_specify = NECESSARY_ATTRIBUTES ;
  392.     register int attr_id ;
  393.     char *attr_name ;
  394.     char *func = "attr_check" ;
  395.     char *attr_name_lookup() ;
  396.  
  397.     /*
  398.      * Determine what attributes must be specified
  399.      */
  400.     if ( ! IS_INTERNAL( scp ) )
  401.         M_OR( must_specify, must_specify, NECESSARY_ATTRIBUTES_EXTERNAL ) ;
  402.  
  403.     if ( IS_RPC( scp ) )
  404.         M_OR( must_specify, must_specify, NECESSARY_ATTRIBUTES_RPC ) ;
  405.  
  406.     if ( IS_UNLISTED( scp ) )
  407.         M_OR( must_specify, must_specify, NECESSARY_ATTRIBUTES_UNLISTED ) ;
  408.     else
  409.         M_OR( must_specify, must_specify, NECESSARY_ATTRIBUTES_LISTED ) ;
  410.  
  411.     /*
  412.      * Check if all necessary attributes have been specified
  413.      *
  414.      * NOTE: None of the necessary attributes can belong to "defaults"
  415.      *            This is why we use the attributes_specified mask.
  416.      */
  417.     M_AND( necessary_and_specified, scp->specified_attributes, must_specify ) ;
  418.     M_XOR( necessary_and_missing, necessary_and_specified, must_specify ) ;
  419.  
  420.     if ( M_ARE_ALL_CLEAR( necessary_and_missing ) )
  421.         return( OK ) ;
  422.     
  423.     for ( attr_id = 0 ; attr_id < SERVICE_ATTRIBUTES ; attr_id++ )
  424.         if ( M_IS_SET( necessary_and_missing, attr_id ) && 
  425.                         ( attr_name = attr_name_lookup( attr_id ) ) != NULL )
  426.             msg( LOG_ERR, func,
  427.                 "Service %s missing attribute %s", scp->id, attr_name ) ;
  428.     return( FAILED ) ;
  429. }
  430.  
  431.  
  432. /*
  433.  * Perform validity checks on the specified entry
  434.  *
  435.  * Also does the following:
  436.  *        1. If this is an internal service, it finds the function that
  437.  *            implements it
  438.  *        2. For RPC services, it finds the program number
  439.  *        3. For non-RPC services, it finds the port number.
  440.  */
  441. PRIVATE status_e check_entry( sp )
  442.     register struct service *sp ;
  443. {
  444.     register struct service_config *scp = CONF( sp ) ;
  445.     char *func = "check_entry" ;
  446.  
  447.     if ( attr_check( scp ) == FAILED )
  448.         return( FAILED ) ;
  449.  
  450.     /*
  451.      * Currently, we cannot intercept:
  452.      *        1) internal services
  453.      *        2) multi-threaded services
  454.      * We clear the INTERCEPT flag without disabling the service.
  455.      */
  456.     if ( IS_INTERCEPTED( scp ) )
  457.     {
  458.         if ( IS_INTERNAL( scp ) )
  459.         {
  460.             msg( LOG_ERR, func,
  461.                 "Internal services cannot be intercepted: %s ", scp->id ) ;
  462.             M_CLEAR( scp->flags, SF_INTERCEPT ) ;
  463.         }
  464.         if ( scp->wait == NO )
  465.         {
  466.             msg( LOG_ERR, func,
  467.                 "Multi-threaded services cannot be intercepted: %s", scp->id ) ;
  468.             M_CLEAR( scp->flags, SF_INTERCEPT ) ;
  469.         }
  470.     }
  471.  
  472.     if ( IS_UNLISTED( scp ) )
  473.     {
  474.         /*
  475.          * XXX:  We don't support unlisted RPC services
  476.          */
  477.         if ( IS_RPC( scp ) )
  478.         {
  479.             msg( LOG_ERR, func,
  480.                 "%s: unlisted RPC services not supported", scp->id ) ;
  481.             return( FAILED ) ;
  482.         }
  483.         return( OK ) ;
  484.     }
  485.  
  486.     if ( IS_INTERNAL( scp ) &&
  487.         ( sp->builtin = find_builtin( scp->name, scp->socket_type ) ) == NULL )
  488.             return( FAILED ) ;
  489.  
  490. #ifndef NO_RPC
  491.     if ( IS_RPC( scp ) )
  492.     {
  493.         struct rpcent *rep = getrpcbyname( scp->name ) ;
  494.  
  495.         if ( rep == NULL )
  496.         {
  497.             msg( LOG_ERR, func, "unknown RPC service: %s", scp->name ) ;
  498.             return( FAILED ) ;
  499.         }
  500.         RPCDATA( scp )->program_number = rep->r_number ;
  501.     }
  502.     else
  503. #endif    /* ! NO_RPC */
  504.     {
  505.         struct servent *sep ;
  506.         u_short service_port ;
  507.  
  508.         /*
  509.          * Check if a protocol was specified.
  510.          * If so, verify it is a proper protocol for the given service.
  511.          * If no protocol was specified, find the protocol for the service
  512.          * and its number.
  513.          */
  514.         if ( SPECIFIED( scp, A_PROTOCOL ) )
  515.         {
  516.             sep = getservbyname( scp->name, scp->protocol.name ) ;
  517.             if ( sep == NULL )
  518.             {
  519.                 msg( LOG_ERR, func, 
  520.                     "service/protocol combination not in /etc/services: %s/%s",
  521.                         scp->name, scp->protocol.name ) ;
  522.                 return( FAILED ) ;
  523.             }
  524.         }
  525.         else
  526.         {
  527.             struct protoent *pep ;
  528.  
  529.             sep = getservbyname( scp->name, (char *)0 ) ;
  530.             if ( sep == NULL )
  531.             {
  532.                 msg( LOG_ERR, func, "Unknown service: %s", scp->name ) ;
  533.                 return( FAILED ) ;
  534.             }
  535.             scp->protocol.name = make_string( 1, sep->s_proto ) ;
  536.             if ( scp->protocol.name == NULL )
  537.             {
  538.                 out_of_memory( func ) ;
  539.                 return( FAILED ) ;
  540.             }
  541.             pep = getprotobyname( sep->s_proto ) ;
  542.             if ( pep == NULL )
  543.             {
  544.                 msg( LOG_ERR, func,
  545.                     "Protocol %s for service %s is not in /etc/protocols",
  546.                         sep->s_proto, scp->name ) ;
  547.                 return( FAILED ) ;
  548.             }
  549.             scp->protocol.value = pep->p_proto ;
  550.         }
  551.  
  552.         service_port = sep->s_port ;        /* s_port is in network-byte-order */
  553.  
  554.         /*
  555.          * If a port was specified, it must be the right one
  556.          */
  557.         if ( SPECIFIED( scp, A_PORT ) && scp->port != ntohs( service_port ) )
  558.         {
  559.             msg( LOG_ERR, func, "Service %s expects port %d, not %d",
  560.                                         scp->name, ntohs( service_port ), scp->port ) ;
  561.             return( FAILED ) ;
  562.         }
  563.         scp->port = ntohs( service_port ) ;
  564.     }
  565.     return( OK ) ;
  566. }
  567.  
  568.  
  569.